import { Component, createRef } from "react";

import { Button, Form, Input, Space } from "antd";
import axios from "axios";

export default class MapBasic extends Component {
  boxRef = createRef<HTMLDivElement>();
  mapIns: any = null;
  polylineIns: any = null;
  markerIns: any = null;

  render() {
    return (
      <div>
        <Space>
          <Button
            type="primary"
            onClick={() =>
              this.line([22.627259, 113.836869], [22.62622, 113.838053])
            }
          >
            连线
          </Button>
        </Space>

        <hr />

        <Form
          layout="inline"
          initialValues={{
            start: "广东省深圳市宝安区西部硅谷",
            end: "广东省深圳市宝安区油麻塘",
          }}
          onFinish={this.onFinish}
        >
          <Form.Item name="start" label="起点" rules={[{ required: true }]}>
            <Input />
          </Form.Item>
          <Form.Item name="end" label="终点" rules={[{ required: true }]}>
            <Input />
          </Form.Item>
          <Form.Item>
            <Button type="primary" htmlType="submit">
              规划路线
            </Button>
          </Form.Item>
        </Form>
        <hr />

        <div
          ref={this.boxRef}
          style={{ height: 500, width: "100%", border: "1px solid #000" }}
        ></div>
      </div>
    );
  }

  onFinish = async (values: any) => {
    const startPoint = await this.geocoder(values.start);
    const endPoint = await this.geocoder(values.end);

    // console.log("startPoint", startPoint);
    // console.log("endPoint", endPoint);
    // this.line(startPoint, endPoint);
    // this.lineTwo(startPoint, endPoint);
    this.lineThree(startPoint, endPoint);
  };

  /**
   * 地址解析
   * @param address 地址信息
   */
  geocoder = async (address: string) => {
    // 1. 调用 腾讯地图提供的 WebServiceAPI https://apis.map.qq.com/ws/geocoder/v1/?address=
    const response = await axios.get("/ws/geocoder/v1/", {
      params: {
        key: "4U3BZ-3JMK3-YRS3Q-RYVXJ-A3DCT-IFFLR",
        address,
      },
    });
    const resp = response.data;
    const {
      location: { lat, lng },
    } = resp.result;

    return [lat, lng];
  };

  /**
   *
   * @param start 起点坐标 [纬度, 经度]
   * @param end 终点坐标   [纬度, 经度]
   */
  line = (start: any, end: any) => {
    const paths = [
      new TMap.LatLng(start[0], start[1]),
      new TMap.LatLng(end[0], end[1]),
    ];

    this.polylineIns.add([
      {
        styleId: "style_blue", //绑定样式名
        paths,
      },
    ]);

    // fit
    this.fit(paths);
  };

  /**
   * 路径规划
   * @param start 起点坐标 [纬度, 经度]
   * @param end 终点坐标   [纬度, 经度]
   */
  lineTwo = async (start: any, end: any) => {
    // 调用路径规划的接口
    const response = await axios.get("/ws/direction/v1/walking/", {
      params: {
        from: `${start[0]},${start[1]}`, // 起点的坐标
        to: `${end[0]},${end[1]}`, // 终点的坐标
        key: "4U3BZ-3JMK3-YRS3Q-RYVXJ-A3DCT-IFFLR",
      },
    });

    // 获取经过压缩的 polyline
    const polyline = response.data.result.routes[0].polyline;
    // 对 polyline 做一个解压
    for (let i = 2; i < polyline.length; i++) {
      polyline[i] = polyline[i - 2] + polyline[i] / 1000000;
    }
    // 对 polyline 转换成 坐标点集合 [[], [], []]
    const result = [];
    for (let i = 0; i < polyline.length; i += 2) {
      result.push([polyline[i], polyline[i + 1]]);
    }
    // 使用 result 来组转 paths
    const paths = result.map((item) => new TMap.LatLng(item[0], item[1]));

    // const paths = [
    //   new TMap.LatLng(start[0], start[1]),
    //   new TMap.LatLng(end[0], end[1]),
    // ];

    this.polylineIns.add([
      {
        styleId: "style_blue", //绑定样式名
        paths,
      },
    ]);

    // fit
    this.fit(paths);
  };

  lineThree = (start: any, end: any) => {
    const driving = new TMap.service.Driving({
      // 新建一个驾车路线规划类
      mp: false, // 是否返回多方案
      policy: "PICKUP,NAV_POINT_FIRST", // 规划策略
    });
    driving
      .search({
        from: new TMap.LatLng(start[0], start[1]),
        to: new TMap.LatLng(end[0], end[1]),
      })
      .then((response: any) => {
        console.log("response", response);
        // 基于 结果获取 paths
        const paths = response.result.routes[0].polyline;

        this.polylineIns.add([
          {
            styleId: "style_blue", //绑定样式名
            paths,
          },
        ]);

        // fit
        this.fit(paths);
      });
  };

  /**
   *
   * @param markers [LatLng, LatLng]
   */
  fit = (markers: any) => {
    const bounds = new TMap.LatLngBounds();
    //判断标注点是否在范围内
    markers.forEach(function (item: any) {
      //若坐标点不在范围内，扩大bounds范围
      if (bounds.isEmpty() || !bounds.contains(item)) {
        bounds.extend(item);
      }
    });
    //设置地图可视范围
    this.mapIns.fitBounds(bounds, {
      padding: 100, // 自适应边距
    });
  };

  componentDidMount(): void {
    // 初始化地图实例
    this.mapIns = new TMap.Map(this.boxRef.current, {
      center: new TMap.LatLng(40.038515, 116.272185), //地图显示中心点
      zoom: 16, //缩放级别
    });

    // 创建 MultiPolyline 图层
    this.polylineIns = new TMap.MultiPolyline({
      id: "polyline-layer", //图层唯一标识
      map: this.mapIns, //设置折线图层显示到哪个地图实例中
      //折线样式定义
      styles: {
        style_blue: new TMap.PolylineStyle({
          color: "#3777FF", //线填充色
          width: 6, //折线宽度
          borderWidth: 5, //边线宽度
          borderColor: "#FFF", //边线颜色
          lineCap: "butt", //线端头方式
        }),
        style_red: new TMap.PolylineStyle({
          color: "#CC0000", //线填充色
          width: 12, //折线宽度
          borderWidth: 15, //边线宽度
          borderColor: "#CCC", //边线颜色
          lineCap: "round", //线端头方式
        }),
      },
      //折线数据定义
      geometries: [
        {
          //第1条线
          id: "pl_1", //折线唯一标识，删除时使用
          styleId: "style_blue", //绑定样式名
          paths: [
            new TMap.LatLng(40.03854, 116.272389),
            new TMap.LatLng(40.038844, 116.27521),
            new TMap.LatLng(40.041407, 116.274738),
          ],
        },
        {
          //第2条线
          id: "pl_2",
          styleId: "style_red",
          paths: [
            new TMap.LatLng(40.039492, 116.271893),
            new TMap.LatLng(40.041562, 116.271421),
            new TMap.LatLng(40.041957, 116.274211),
          ],
        },
      ],
    });

    // 创建 MultiMarker 图层
    this.markerIns = new TMap.MultiMarker({
      map: this.mapIns,
    });

    // 绑定 点击事件
    this.mapIns.on("click", (event: any) => {
      console.log("click", event);
      // 向 event.latLng 添加一个点
      this.markerIns.add([
        {
          position: event.latLng,
        },
      ]);
    });
  }

  componentWillUnmount(): void {
    // 销毁地图实例
    this.mapIns.destroy();
  }
}
